package com.lagou.service;

import com.lagou.WxxApplication;
import com.lagou.entity.Zookeeper;
import com.lagou.handler.NewUserClientHandler;
import com.lagou.protocol.RpcRequest;
import com.lagou.util.JSONSerializer;
import com.lagou.util.RpcDecoder;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.string.StringEncoder;
import org.I0Itec.zkclient.ZkClient;
import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.data.Stat;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements IUserService {
    static String  zookeeperpath="/provide_path/";
    //将来客户单要远程调用的方法
    public String sayHello(String msg) {
        System.out.println("are you ok ? "+msg);
        return "服务器返回数据 : "+msg;
    }

    @Override
    public String getResult(Object object) {
        System.out.println("调用成功：：：：："+object);
        return "success";
    }
    //使用fastjson反序列化


    //创建一个方法启动服务器
    public static void startServer(String ip , int port) throws Exception {
        createNodeZookeeper();
        NioEventLoopGroup bossGroup = new NioEventLoopGroup();
        NioEventLoopGroup workerGroup = new NioEventLoopGroup();

        ServerBootstrap serverBootstrap = new ServerBootstrap();
        serverBootstrap.group(bossGroup,workerGroup)
                .channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    protected void initChannel(SocketChannel ch) throws Exception {
                        ChannelPipeline pipeline = ch.pipeline();
                        pipeline.addLast(new StringEncoder());
                        pipeline.addLast(new RpcDecoder(RpcRequest.class, new JSONSerializer()));
                        pipeline.addLast(new NewUserClientHandler());

                    }
                });
        serverBootstrap.bind(ip,port).sync();
    }
    //创建zookeeper节点
    public static void createNodeZookeeper() throws Exception {
//        ZkClient zkClient = new ZkClient("119.3.173.114:2181");
//        System.out.println("会话被创建了");
//        zkClient.createEphemeral(path,data);

        RetryPolicy exponentialBackoffRetry = new ExponentialBackoffRetry(1000, 3);
        //使用fluent变成风格
        CuratorFramework curatorClient = CuratorFrameworkFactory.builder()
                .connectString("119.3.173.114:2181")
                .sessionTimeoutMs(1000)
                .connectionTimeoutMs(3000)
                .retryPolicy(exponentialBackoffRetry)
                .namespace("base")  //独立的命名空间
                .build();
        curatorClient.start();
        System.out.println("会话建立成功");
        String nodePath=zookeeperpath+ WxxApplication.ip+":"+WxxApplication.port;

        curatorClient.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL).forPath(nodePath);
//        Stat stat = new Stat();
//        curatorClient.getData().storingStatIn(stat).forPath(nodePath);
//        curatorClient.setData().withVersion(stat.getVersion()).forPath(nodePath,String.valueOf(System.currentTimeMillis()).getBytes());
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                while (true){
                    try {
                        Stat stat = new Stat();
                        curatorClient.getData().storingStatIn(stat).forPath(nodePath);
                        curatorClient.setData().withVersion(stat.getVersion()).forPath(nodePath,String.valueOf(System.currentTimeMillis()).getBytes());
                        Thread.sleep(5000);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        });

        thread.start();
    }


    public static void main(String[] args) throws Exception {
        createNodeZookeeper();
    }

}
